﻿using FluentValidation;
using MediatR;

namespace CQRSLearn.Behaviors
{
    public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : class
    {
        private readonly IEnumerable<IValidator<TRequest>> _validators;

        public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
        {
            _validators = validators;
        }

        public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
        {
            ArgumentNullException.ThrowIfNull(next);

            if (_validators.Any()) {
                var context = new ValidationContext<TRequest>(request);

                var validationResult=await Task.WhenAll(
                    _validators.Select(v=>v.ValidateAsync(context,cancellationToken))).ConfigureAwait(false);

                var failures = validationResult
                    .Where(r => r.Errors.Count > 0)
                    .SelectMany(r=>r.Errors).ToList();

                if (failures.Any()) {
                    throw new FluentValidation.ValidationException(failures);
                }


            }
            return await next().ConfigureAwait(false);
        }
    }
}
